﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Design;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System.Xml;
using BrightIdeasSoftware;

namespace HML.SkinTool
{
    public partial class MainForm : Form
    {
        #region 字段

        /// <summary>
        /// 主题对象列表选项
        /// </summary>
        private List<ISkinObject> skinObjectList = new List<ISkinObject>();

        /// <summary>
        /// 主题对象所在的程序集
        /// </summary>
        private Assembly[] assemblyArr = new Assembly[] { typeof(HML.SkinManager).Assembly };

        /// <summary>
        /// 保存窗体最后打开记录
        /// </summary>
        private string saveFileDialogStr = null;

        #endregion

        public MainForm()
        {
            InitializeComponent();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            this.SkinDropDownListPlus_BindList(Skins.Dark.ToString());
            SkinManager.Apply(Skins.Dark.ToString());

            this.ControlComboBox_BindList(this.assemblyArr);

            this.SkinStyleComboBox_BindList(SkinStyle.Normal);

            this.propertyGrid.CellClick += this.PropertyGrid_CellClick;
            this.propertyGrid.PropertyValueChanged += this.PropertyGrid_PropertyValueChanged;
            this.PropertyGrid_BindList(this.controlDropDownListPlus.SelectedItem == null ? null : (ISkinObject)this.controlDropDownListPlus.SelectedItem.Tag);

            SkinForm8_0_0_6 form = new SkinForm8_0_0_6() { TopMost = false, TopLevel = false, Dock = DockStyle.Fill, FormBorderStyle = FormBorderStyle.None, Visible = true, Parent = this.splitContainer1.Panel2 };
        }

        /// <summary>
        /// 主题列表绑定
        /// </summary>
        /// <param name="skinName">ComboBox要选中主题名称</param>
        private void SkinDropDownListPlus_BindList(string skinName)
        {
            this.skinDropDownListPlus.SelectedItemsChanged -= this.SkinDropDownListPlus_SelectedItemsChanged;

            DropDownListPlusItem selectItem = null;
            DropDownListPlusItemCollection dropDownListPlusItemCollection = new DropDownListPlusItemCollection();
            foreach (string name in SkinManager.GetRegisterSkinNames())
            {
                DropDownListPlusItem item = new DropDownListPlusItem() { Text = name };
                dropDownListPlusItemCollection.Add(item);
                if (name == skinName)
                {
                    selectItem = item;
                }
            }
            this.skinDropDownListPlus.BindItemsSource(dropDownListPlusItemCollection, selectItem);

            this.skinDropDownListPlus.SelectedItemsChanged += this.SkinDropDownListPlus_SelectedItemsChanged;
        }
        /// <summary>
        /// 主题更改事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SkinDropDownListPlus_SelectedItemsChanged(object sender, EventArgs e)
        {
            SkinManager.Apply(this.skinDropDownListPlus.SelectedItem.Text);

            foreach (ISkinObject skinObject in this.skinObjectList)
            {
                skinObject.OnSkinChanged();
            }

            this.PropertyGrid_BindList(this.controlDropDownListPlus.SelectedItem == null ? null : (ISkinObject)this.controlDropDownListPlus.SelectedItem.Tag); ;
        }

        /// <summary>
        /// 控件列表绑定
        /// </summary>
        /// <param name="assemblyArr"></param>
        private void ControlComboBox_BindList(Assembly[] assemblyArr)
        {
            this.controlDropDownListPlus.SelectedItemsChanged -= this.ControlDropDownListPlus_SelectedItemsChanged;

            List<ISkinObject> skinObjectList_tmp = new List<ISkinObject>();
            for (int j = 0; j < assemblyArr.Length; j++)
            {
                Type[] skinObjectTypeArr = assemblyArr[j].GetTypes();
                for (int i = 0; i < skinObjectTypeArr.Length; i++)
                {
                    if (skinObjectTypeArr[i].GetInterface(typeof(ISkinObject).FullName) == typeof(ISkinObject) && !skinObjectTypeArr[i].IsAbstract)
                    {
                        ISkinObject skinObject = null;
                        ConstructorInfo skinObject_constructor = skinObjectTypeArr[i].GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { }, null);
                        if (skinObject_constructor == null)
                        {
                            throw new SkinException("”" + skinObjectTypeArr[i].FullName + "“必须指定一个无参构造函数提供给SkinTool主题编辑器使用。");
                        }

                        skinObject = (ISkinObject)skinObject_constructor.Invoke(null);
                        if (skinObject.SkinObjectXmlMetadata.ClassName == skinObjectTypeArr[i].Name)
                        {
                            skinObject.SkinEnabled = SkinEnabledState.True;
                            skinObjectList_tmp.Add(skinObject);
                        }
                    }
                }
            }
            skinObjectList_tmp = skinObjectList_tmp.OrderBy(a => a.GetType().Name).ToList();
            DropDownListPlusItemCollection dropDownListPlusItemCollection = new DropDownListPlusItemCollection();
            foreach (ISkinObject skinObject in skinObjectList_tmp)
            {
                Type type = skinObject.GetType();
                string str = type.Name + " [" + ((DescriptionAttribute)type.GetCustomAttributes(typeof(DescriptionAttribute), true)[0]).Description + "]";
                dropDownListPlusItemCollection.Add(new DropDownListPlusItem() { Tag = skinObject, Text = str });
            }

            this.skinObjectList = skinObjectList_tmp;
            this.controlDropDownListPlus.BindItemsSource(dropDownListPlusItemCollection);

            this.controlDropDownListPlus.SelectedItemsChanged += this.ControlDropDownListPlus_SelectedItemsChanged;
        }
        /// <summary>
        /// 控件更改事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ControlDropDownListPlus_SelectedItemsChanged(object sender, EventArgs e)
        {
            this.PropertyGrid_BindList((ISkinObject)this.controlDropDownListPlus.SelectedItem.Tag);
        }

        /// <summary>
        /// 主题风格列表绑定
        /// </summary>
        /// <param name="skinStyle"></param>
        private void SkinStyleComboBox_BindList(SkinStyle skinStyle)
        {
            this.skinStyleDropDownListPlus.SelectedItemsChanged -= this.SkinStyleDropDownListPlus_SelectedItemsChanged;

            DropDownListPlusItem selectItem = null;
            DropDownListPlusItemCollection dropDownListPlusItemCollection = new DropDownListPlusItemCollection();
            foreach (string name in Enum.GetNames(typeof(SkinStyle)))
            {
                DropDownListPlusItem item = new DropDownListPlusItem() { Text = name };
                dropDownListPlusItemCollection.Add(item);
                if (name == skinStyle.ToString())
                {
                    selectItem = item;
                }
            }
            this.skinStyleDropDownListPlus.BindItemsSource(dropDownListPlusItemCollection, selectItem);

            foreach (ISkinObject skinObject in this.skinObjectList)
            {
                skinObject.OnSkinChanged();
            }

            this.skinStyleDropDownListPlus.SelectedItemsChanged += this.SkinStyleDropDownListPlus_SelectedItemsChanged;
        }
        /// <summary>
        /// 主题风格更改事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SkinStyleDropDownListPlus_SelectedItemsChanged(object sender, EventArgs e)
        {
            SkinManager.Apply(this.skinDropDownListPlus.SelectedItem.Text);
            ISkinObject skinObject = (ISkinObject)this.controlDropDownListPlus.SelectedItem.Tag;
            skinObject.SkinStyle = (SkinStyle)Enum.Parse(typeof(SkinStyle), this.skinStyleDropDownListPlus.SelectedItem.Text);
            skinObject.OnSkinChanged();
            this.PropertyGrid_BindList(skinObject);
        }

        /// <summary>
        /// 主题属性列表绑定
        /// </summary>
        private void PropertyGrid_BindList(ISkinObject skinObject)
        {
            if (skinObject == null)
            {
                this.propertyGrid.Roots = null;
                return;
            }

            this.propertyGrid.Roots = this.GetPropertyTree(skinObject);
            this.propertyGrid.ExpandAll();
        }
        /// <summary>
        /// 主题属性更改
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PropertyGrid_PropertyValueChanged(object sender, TreeListViewPropertyGridValueChangedEventArgs e)
        {
            ISkinObject skinObject = (ISkinObject)this.controlDropDownListPlus.SelectedItem.Tag;
            string xpath = "Skin/" + Assembly.GetAssembly(skinObject.GetType()).GetName().Name + "/" + skinObject.GetType().Name + "/" + this.skinStyleDropDownListPlus.SelectedItem.Text + e.Item.XPath;

            if (e.Item.PropertyInfo.PropertyType == typeof(Color) || e.Item.PropertyInfo.PropertyType.IsSubclassOf(typeof(Color)))
            {
                this.SetXPathSkinValue(this.skinDropDownListPlus.SelectedItem.Text, xpath, (Color)e.Item.PropertyValue);
            }

           ((ISkinObject)this.controlDropDownListPlus.SelectedItem.Tag).OnSkinChanged();

            SkinManager.Apply(this.skinDropDownListPlus.SelectedItem.Text);
        }
        /// <summary>
        /// 单击属性时显示属性描述
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PropertyGrid_CellClick(object sender, CellClickEventArgs e)
        {
            this.descriptionLabel.Text = e.Model == null ? "" : (((TreeListViewPropertyGridItem)e.Model)).PropertyDescription;
        }

        /// <summary>
        /// 同步主题风格
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void skinStyleSyncButton_Click(object sender, EventArgs e)
        {
            同步主题风格Form form = new 同步主题风格Form((SkinStyle)Enum.Parse(typeof(SkinStyle), this.skinStyleDropDownListPlus.SelectedItem.Text));
            try
            {
                if (form.ShowDialog(this) == DialogResult.OK)
                {
                    string[] names = new string[form.skinStyleCheckedListBox.CheckedItems.Count];
                    form.skinStyleCheckedListBox.CheckedItems.CopyTo(names, 0);

                    Dictionary<string, XmlDocument> skins = (Dictionary<string, XmlDocument>)typeof(SkinManager).GetProperty("AllSkins", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null, null);
                    XmlDocument skinDocument = skins[this.skinDropDownListPlus.SelectedItem.Text];

                    Type type = ((ISkinObject)this.controlDropDownListPlus.SelectedItem.Tag).GetType();
                    string skinObjectXPath = "Skin/" + Assembly.GetAssembly(type).GetName().Name + "/" + type.Name;
                    XmlNode skinObjectNode = skinDocument.SelectSingleNode(skinObjectXPath);

                    XmlNode normal_node = skinObjectNode.SelectSingleNode(SkinStyle.Normal.ToString());
                    if (normal_node == null)
                    {
                        normal_node.AppendChild(skinDocument.CreateNode(XmlNodeType.Element, SkinStyle.Normal.ToString(), ""));
                    }

                    for (int i = 0; i < names.Length; i++)
                    {
                        XmlNode new_node = skinObjectNode.SelectSingleNode(names[i]);
                        if (new_node == null)
                        {
                            new_node = skinDocument.CreateNode(XmlNodeType.Element, names[i], "");
                        }
                        else
                        {
                            new_node.RemoveAll();
                        }
                        foreach (XmlNode node in normal_node.ChildNodes)
                        {
                            new_node.AppendChild(node.CloneNode(true));
                        }
                        skinObjectNode.AppendChild(new_node);
                    }
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + ex.StackTrace);
            }
            finally
            {
                form.Dispose();
            }
        }

        private void 文件ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (sender == this.文件ToolStripMenuItem)
            {
                this.关闭主题ToolStripMenuItem.Enabled = !(this.skinDropDownListPlus.SelectedItem == null || Enum.GetNames(typeof(Skins)).ToList<string>().Where(a => a == this.skinDropDownListPlus.SelectedItem.Text).Count() > 0);
            }
        }

        private void 新建主题ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            新建主题Form form = new 新建主题Form();
            try
            {
                if (form.ShowDialog(this) == DialogResult.OK)
                {
                    Dictionary<string, XmlDocument> skins = (Dictionary<string, XmlDocument>)typeof(SkinManager).GetProperty("AllSkins", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null, null);
                    XmlDocument xmlDocument = skins[form.skinsComboBox.SelectedItem.ToString()];
                    skins[form.skinNameTextBox.Text.Trim()] = (XmlDocument)xmlDocument.CloneNode(true);

                    SkinDropDownListPlus_BindList(form.skinNameTextBox.Text.Trim());
                    this.PropertyGrid_BindList((ISkinObject)this.controlDropDownListPlus.SelectedItem.Tag);
                    SkinManager.Apply(this.skinDropDownListPlus.SelectedItem.Text);
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + ex.StackTrace);
            }
            finally
            {
                form.Dispose();
            }
        }

        private void 打开主题ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            try
            {
                openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                openFileDialog.Filter = ".xml|*.xml";
                openFileDialog.FilterIndex = 1;
                openFileDialog.RestoreDirectory = true;
                openFileDialog.Title = "打开主题";
                openFileDialog.ShowHelp = false;

                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    string skinName = Path.GetFileNameWithoutExtension(openFileDialog.FileName);
                    Dictionary<string, XmlDocument> skins = (Dictionary<string, XmlDocument>)typeof(SkinManager).GetProperty("AllSkins", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null, null);
                    if (skins.ContainsKey(skinName))
                    {
                        MessageBox.Show("已存在该名称主题主题", "操作取消");
                        return;
                    }
                    XmlDocument xmlDocument = new XmlDocument();
                    xmlDocument.Load(openFileDialog.FileName);
                    skins[skinName] = xmlDocument;

                    SkinDropDownListPlus_BindList(skinName);
                    this.PropertyGrid_BindList((ISkinObject)this.controlDropDownListPlus.SelectedItem.Tag);
                    SkinManager.Apply(this.skinDropDownListPlus.SelectedItem.Text);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + ex.StackTrace);
            }
            finally
            {
                openFileDialog.Dispose();
            }
        }

        private void 保存主题ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            try
            {
                if (!String.IsNullOrWhiteSpace(this.saveFileDialogStr) && Directory.Exists(this.saveFileDialogStr))
                {
                    saveFileDialog.InitialDirectory = this.saveFileDialogStr;
                }
                else
                {
                    saveFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                }
                saveFileDialog.Filter = ".xml|*.xml";
                saveFileDialog.FilterIndex = 1;
                saveFileDialog.RestoreDirectory = true;
                saveFileDialog.Title = "保存主题";
                saveFileDialog.ShowHelp = false;
                saveFileDialog.FileName = this.skinDropDownListPlus.SelectedItem.Text;

                if (saveFileDialog.ShowDialog() == DialogResult.OK)
                {
                    this.saveFileDialogStr = Path.GetDirectoryName(saveFileDialog.FileName);
                    Dictionary<string, XmlDocument> skins = (Dictionary<string, XmlDocument>)typeof(SkinManager).GetProperty("AllSkins", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null, null);
                    XmlDocument skinDocument = skins[this.skinDropDownListPlus.SelectedItem.Text];

                    string[] names = new string[] { SkinStyle.Warn.ToString(), SkinStyle.Success.ToString(), SkinStyle.Error.ToString() };

                    XmlNode skinNode = skinDocument.SelectSingleNode("Skin");
                    foreach (XmlNode namespaceNode in skinNode)
                    {
                        foreach (XmlNode skinObjectNode in namespaceNode)
                        {
                            foreach (string name in names)
                            {
                                if (skinObjectNode[name] == null)
                                {
                                    XmlNode styleVariety = skinDocument.CreateNode(XmlNodeType.Element, name, "");
                                    foreach (XmlNode oldNode in skinObjectNode[SkinStyle.Normal.ToString()].ChildNodes)
                                    {
                                        styleVariety.AppendChild(oldNode.CloneNode(true));
                                    }
                                    skinObjectNode.AppendChild(styleVariety);
                                }
                            }
                        }
                    }

                    XmlDocument skinDocument_copy = (XmlDocument)skinDocument.CloneNode(true);
                    this.ValidSkinXml(skinDocument, skinDocument_copy);

                    skins[this.skinDropDownListPlus.SelectedItem.Text].Save(saveFileDialog.FileName);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + ex.StackTrace);
            }
            finally
            {
                saveFileDialog.Dispose();
            }
        }

        private void 关闭主题ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.skinDropDownListPlus.SelectedItem != null)
                {
                    Dictionary<string, XmlDocument> skins = (Dictionary<string, XmlDocument>)typeof(SkinManager).GetProperty("AllSkins", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null, null);
                    skins.Remove(this.skinDropDownListPlus.SelectedItem.Text);

                    this.SkinDropDownListPlus_BindList(Skins.Dark.ToString());
                    this.ControlComboBox_BindList(this.assemblyArr);
                    this.PropertyGrid_BindList((ISkinObject)this.controlDropDownListPlus.SelectedItem.Tag);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + ex.StackTrace);
            }
        }

        private void 查看当前主题XMLToolStripMenuItem_Click(object sender, EventArgs e)
        {
            查看当前主题XMLForm xMLForm = new 查看当前主题XMLForm();
            xMLForm.FormClosed += this.XMLForm_FormClosed;

            Dictionary<string, XmlDocument> skins = (Dictionary<string, XmlDocument>)typeof(SkinManager).GetProperty("AllSkins", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null, null);

            StringBuilder formattedXml = new StringBuilder();
            using (StringWriter stringWriter = new StringWriter(formattedXml))
            {
                skins[this.skinDropDownListPlus.SelectedItem.Text].Save(stringWriter);
            }

            xMLForm.TextArea.Text = formattedXml.ToString();
            xMLForm.Show(this);
        }

        private void XMLForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            ((Form)sender).Dispose();
        }


        #region 私有方法

        /// <summary>
        /// 获取主题属性树
        /// </summary>
        /// <param name="skinObject"></param>
        /// <returns></returns>
        private List<TreeListViewPropertyGridItem> GetPropertyTree(ISkinObject skinObject)
        {
            string xpath = "/StyleAppearance";
            List<TreeListViewPropertyGridItem> items = new List<TreeListViewPropertyGridItem>();
            object obj = (AppearanceObjectBase)skinObject.GetType().GetProperty("StyleAppearance", BindingFlags.Public | BindingFlags.Instance).GetValue(skinObject, null);
            RecurrenceGetPropertyItem(obj, items, xpath);
            return items;


            void RecurrenceGetPropertyItem(object ownerObject, List<TreeListViewPropertyGridItem> list, string xpath_tmp)
            {
                list.Sort(new TreeListViewPropertyGridItem.Comparer());

                PropertyInfo[] propertyInfos = ownerObject.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
                foreach (PropertyInfo info in propertyInfos)
                {
                    if (info.GetCustomAttributes(typeof(SkinPropertyAttribute), true) != null)
                    {
                        string tmp = xpath_tmp + "/" + info.Name;
                        SkinPropertyAttribute skinPropertyAttribute = (SkinPropertyAttribute)info.GetCustomAttributes(typeof(SkinPropertyAttribute), true)[0];
                        if (skinPropertyAttribute.Enabled)
                        {
                            string objectDescription = "";
                            if (info.GetCustomAttributes(typeof(DescriptionAttribute), true) != null)
                            {
                                objectDescription = ((DescriptionAttribute)info.GetCustomAttributes(typeof(DescriptionAttribute), true)[0]).Description;
                            }

                            float order = 0f;
                            if (info.GetCustomAttributes(typeof(PropertyOrderAttribute), true) != null)
                            {
                                order = ((PropertyOrderAttribute)info.GetCustomAttributes(typeof(PropertyOrderAttribute), true)[0]).SerialNumber;
                            }

                            object propertyValue = null;
                            string propertyValueStr = "";
                            string propertyFieldName = "skin" + info.Name;
                            FieldInfo propertyField = ownerObject.GetType().GetField(propertyFieldName, BindingFlags.NonPublic | BindingFlags.Instance);
                            if (propertyField == null)
                            {
                                propertyFieldName = "_" + propertyFieldName;
                                ownerObject.GetType().GetField(propertyFieldName, BindingFlags.NonPublic | BindingFlags.Instance);
                            }
                            if (info.PropertyType.IsSubclassOf(typeof(AppearanceObjectBase)))
                            {
                                propertyValue = info.GetValue(ownerObject, null);
                            }
                            else
                            {
                                propertyValue = propertyField.GetValue(ownerObject);
                                propertyValueStr = TypeDescriptor.GetConverter(info.PropertyType).ConvertTo(propertyValue, typeof(string)) as string;
                            }

                            bool isEdit = (!info.PropertyType.IsSubclassOf(typeof(AppearanceObjectBase)));

                            EditorAttribute editorAttribute = null;
                            if (info.IsDefined(typeof(EditorAttribute), true))
                            {
                                editorAttribute = ((EditorAttribute)info.GetCustomAttributes(typeof(EditorAttribute), true)[0]);
                            }
                            else if (info.PropertyType.IsDefined(typeof(EditorAttribute), true))
                            {
                                editorAttribute = ((EditorAttribute)info.PropertyType.GetCustomAttributes(typeof(EditorAttribute), true)[0]);
                            }

                            TreeListViewPropertyGridItem propertyItem = new TreeListViewPropertyGridItem(info.Name, propertyValue, propertyValueStr, objectDescription, info, order, tmp, skinPropertyAttribute.EnvironmentProperty, isEdit, editorAttribute, ownerObject);
                            list.Add(propertyItem);

                            if (info.PropertyType.IsSubclassOf(typeof(AppearanceObjectBase)))
                            {
                                RecurrenceGetPropertyItem(info.GetValue(ownerObject, null), propertyItem.Children, tmp);
                            }
                        }
                    }

                }

            }
        }

        /// <summary>
        /// 验证主题xml文档
        /// </summary>
        /// <param name="skinDocument"></param>
        /// <param name="skinDocument_copy"></param>
        private void ValidSkinXml(XmlDocument skinDocument, XmlDocument skinDocument_copy)
        {
            string[] names = new string[] { SkinStyle.Normal.ToString(), SkinStyle.Warn.ToString(), SkinStyle.Success.ToString(), SkinStyle.Error.ToString() };

            foreach (DropDownListPlusItem item in this.controlDropDownListPlus.ItemsSource)
            {
                for (int i = 0; i < names.Length; i++)
                {
                    Type type = item.Tag.GetType();
                    PropertyInfo property = type.GetProperty("StyleAppearance", BindingFlags.Public | BindingFlags.Instance);
                    string skinObjectXPath = "Skin/" + Assembly.GetAssembly(type).GetName().Name + "/" + type.Name + "/" + names[i];
                    this.RecurrenceSyncSkinValue(skinDocument, skinDocument_copy, item.Tag, skinObjectXPath, property);
                }
            }

            //XmlNode skinNode = skinDocument_copy.SelectSingleNode("Skin");
            //foreach (XmlNode namespaceNode in skinNode)
            //{
            //    foreach (XmlNode skinObjectNode in namespaceNode)
            //    {
            //        ISkinObject obj= controlinfo_list_tmp.Where(a => Assembly.GetAssembly(a.GetType()).GetName().Name == namespaceNode.Name && a.GetType().Name == skinObjectNode.Name).FirstOrDefault();
            //        if (obj == null)
            //        {
            //            skinObjectNode.ParentNode.RemoveChild(skinObjectNode);
            //        }
            //        else
            //        {
            //            RecurrenceSyncXPath
            //        }

            //        foreach (string name in names)
            //        {
            //            if (skinObjectNode[name] == null)
            //            {
            //                XmlNode styleVariety = skinDocument.CreateNode(XmlNodeType.Element, name, "");
            //                foreach (XmlNode oldNode in skinObjectNode[SkinStyle.Normal.ToString()].ChildNodes)
            //                {
            //                    styleVariety.AppendChild(oldNode.CloneNode(true));
            //                }
            //                skinObjectNode.AppendChild(styleVariety);
            //            }
            //        }
            //    }
            //}


        }

        /// <summary>
        /// 递归同步主题对象的主题属性到主题文件配置上
        /// </summary>
        /// <param name="skinDocument">要同步的主题文件配置</param
        /// <param name="skinDocument_copy">要同步的主题文件配置</param
        /// <param name="propertyOwnerObject">属性所在对象</param>
        /// <param name="propertyOwnerXPath">属性所在对象在主题配置文件的XPath路径</param>
        /// <param name="property">要同步的属性元数据</param>
        private void RecurrenceSyncSkinValue(XmlDocument skinDocument, XmlDocument skinDocument_copy, object propertyOwnerObject, string propertyOwnerXPath, PropertyInfo property)
        {
            string propertyXPath = propertyOwnerXPath + "/" + property.Name;

            if (property.PropertyType.IsSubclassOf(typeof(AppearanceObjectBase)))
            {
                PropertyInfo[] childrenPropertys = property.PropertyType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
                foreach (PropertyInfo childrenProperty in childrenPropertys)
                {
                    if (childrenProperty.IsDefined(typeof(SkinPropertyAttribute), true))
                    {
                        SkinPropertyAttribute skinPropertyAttribute = (SkinPropertyAttribute)childrenProperty.GetCustomAttributes(typeof(SkinPropertyAttribute), true)[0];
                        if (skinPropertyAttribute.Enabled)
                        {
                            RecurrenceSyncSkinValue(skinDocument, skinDocument_copy, property.GetValue(propertyOwnerObject, null), propertyXPath, childrenProperty);
                        }
                    }
                }
            }
            else
            {
                XmlNode xmlNode = skinDocument.SelectSingleNode(propertyXPath);
                if (xmlNode == null)
                {
                    this.CreateXPathSkinNode(skinDocument, property.PropertyType, propertyXPath);
                }
                else
                {
                    //XmlNode xmlNode_tmp = skinDocument_copy.SelectSingleNode(propertyXPath);
                    //xmlNode_tmp.ParentNode.RemoveChild(xmlNode_tmp);
                    //XmlNode xmlParentNode = xmlNode_tmp.ParentNode;
                    //xmlParentNode.RemoveChild(xmlNode_tmp);

                    //while (true)
                    //{
                    //    if (xmlParentNode == null || xmlParentNode.HasChildNodes)
                    //    {
                    //        break;
                    //    }

                    //    XmlNode node = xmlParentNode;
                    //    xmlParentNode = xmlParentNode.ParentNode;
                    //    if (xmlParentNode != null)
                    //    {
                    //        xmlParentNode.RemoveChild(node);
                    //    }
                    //}

                    //XmlNode xmlParentNode = xmlNode.ParentNode;
                    //xmlParentNode.RemoveChild(xmlNode);

                    //while (true)
                    //{
                    //    if (xmlParentNode == null || xmlParentNode.ChildNodes.Count > 0)
                    //    {
                    //        break;
                    //    }

                    //    XmlNode node = xmlParentNode;
                    //    xmlParentNode = xmlParentNode.ParentNode;
                    //    if (xmlParentNode != null)
                    //    {
                    //        xmlParentNode.RemoveChild(node);
                    //    }
                    //}
                }
            }
        }

        /// <summary>
        /// 根据主题获取指定xPath路径值
        /// </summary>
        /// <param name="skinName">主题名称</param>
        /// <param name="xPath">主题对象的属性在xml主题文件的xpath路径 (格式：Skin/程序集名称/继承ISkinObject类的类名/风格名称/[嵌套对象名称/...]属性名称)</param>
        /// <param name="value">颜色值</param>
        /// <returns></returns>
        public void SetXPathSkinValue(string skinName, string xPath, Color value)
        {
            Dictionary<string, XmlDocument> skins = (Dictionary<string, XmlDocument>)typeof(SkinManager).GetProperty("AllSkins", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null, null);
            XmlNode xmlNode = skins[skinName].SelectSingleNode(xPath);
            if (xmlNode == null)
            {
                CreateXPathSkinNode(skins[skinName], typeof(Color), xPath);
                xmlNode = skins[skinName].SelectSingleNode(xPath);
                xmlNode.Attributes.Append(skins[skinName].CreateAttribute("ValueType"));
                xmlNode.Attributes["ValueType"].Value = typeof(Color).FullName;
                xmlNode.Attributes.Append(skins[skinName].CreateAttribute("Value"));
            }

            if (value.IsNamedColor)
            {
                xmlNode.Attributes["Value"].Value = value.Name;
            }
            else if (value.A == 255)
            {
                xmlNode.Attributes["Value"].Value = string.Format("{0},{1},{2}", value.R, value.G, value.B);
            }
            else if (value.A == 0 && value.R == 0 && value.G == 0 && value.B == 0)
            {
                xmlNode.Attributes["Value"].Value = string.Empty;
            }
            else
            {
                xmlNode.Attributes["Value"].Value = string.Format("{0},{1},{2},{3}", value.A, value.R, value.G, value.B);
            }

        }

        /// <summary>
        /// 根据xPath创建主题节点
        /// </summary>
        /// <param name="skinDocument">主题文档</param>
        /// <param name="DataType">数据类型</param>
        /// <param name="xPath">主题对象的属性在xml主题文件的xpath路径 (格式：Skin/程序集名称/继承ISkinObject类的类名/风格名称/[嵌套对象名称/...]属性名称)</param>
        private void CreateXPathSkinNode(XmlDocument skinDocument, Type DataType, string xPath)
        {
            XmlNode node = (XmlNode)skinDocument;
            string[] nameArr = xPath.Trim('/').Split('/');
            for (int i = 0; i < nameArr.Length; i++)
            {
                XmlNode child = node.SelectSingleNode(nameArr[i]);
                if (child == null)
                {
                    child = skinDocument.CreateElement(nameArr[i]);
                    if (DataType == typeof(Color))
                    {
                        child.Attributes.Append(skinDocument.CreateAttribute("ValueType"));
                        child.Attributes["ValueType"].Value = typeof(Color).FullName;
                        child.Attributes.Append(skinDocument.CreateAttribute("Value"));
                        child.Attributes["Value"].Value = "";
                    }
                    node.AppendChild(child);
                }
                node = child;
            }
        }

        #endregion

    }
}

